package com.goat.model.element;

import com.goat.model.manager.EleManager;
import com.goat.model.manager.GameLoader;
import com.goat.model.manager.enumCls.GameElement;

import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;

public class Player extends BaseElement{
    //四属性表示状态，现在还不太能理解，只知道这样可以实现左上、左下等的移动
    //还有单属性、双属性。<单属性>就是使用<一个枚举>来表示<上下左右>
    /**
     * 游戏中有非常多的判定，要灵活使用《判定属性》，很多状态值也使用判定属性的多状态
     */
    private boolean left=false;
    private boolean right=false;
    private boolean up=false;
    private boolean down=false;  //move()
                                              //都是在keyListen(boolean f, int key)中改变状态的
    //方向，初始是向上的，用来改变图片的变量
    private String direct="up";//initShoter()  updateImage()

    //射击状态
    private boolean shoter=false;

    //使用map来管理存储图片，实际上是加载器
    //now, it is got from the Loader
    private static Map<String,ImageIcon> imageMap= GameLoader.getImageIconMap();

    //This constructor also leave the history stage
    public Player(int x, int y, int w, int h, ImageIcon imageIcon) {
        super(x, y, w, h, imageIcon);
        /*imageMap=new HashMap<>();
        //图片的加载实际上是加载器的工作
        imageMap.put("left",new ImageIcon("image\\tank\\play1\\player1_left.png"));
        imageMap.put("right",new ImageIcon("image\\tank\\play1\\player1_right.png"));
        imageMap.put("down",new ImageIcon("image\\tank\\play1\\player1_down.png"));
        imageMap.put("up",new ImageIcon("image\\tank\\play1\\player1_up.png"));*/
    }

    public Player(){}//空参构造，创建对象的工具人，目的是createElement

    //对象自己的事情自己做
    @Override
    public void showElement(Graphics g) {
        g.drawImage(this.getImageIcon().getImage(),this.getX(),this.getY(),
                this.getW(),this.getH(),null);
    }

    //改变状态，被监听调用
    @Override
    public void keyListen(boolean f, int key) {
        //改变状态
        if(f){//按下键盘就动
            /*switch (key){
                case 37: setX(getX()-10);break;
                case 38: setY(getY()-10);break;
                case 39: setX(getX()+10);break;
                case 40: setY(getY()+10);break;
            }*/
            switch (key){//控制了player只能往一个direct移动
                case 65: left=true;right=false;up=false;down=false;direct="left";break;
                case 87: up=true;down=false;left=false;right=false;direct="up";break;
                case 68: right=true;left=false;up=false;down=false;direct="right";break;
                case 83: down=true;up=false;left=false;right=false;direct="down";break;
                case 32:shoter=true;break;
            }
        }
        else {//松开就不动
            switch (key){
                case 65: left=false;break;
                case 87: up=false;break;
                case 68: right=false;break;
                case 83: down=false;break;
                case 32:shoter=false;break;
            }
        }

        //这其实是主线程干的活               所谓主线程干的活，是指在本类中封装好方法，被主线程调用
        //移动位置,实际上是数据的改变
        //约定好数据的改变是主线程的工作
        //必要性：Player不是一个单独的线程，没有办法根据状态持续地改变数据
        //            本例中，如果持续按着移动键，listener不会重复调用player的方法，
        //            就无法实现持续移动，因此通过主线程，持续的根据状态改变位置(数据)

    }


    //根据状态改变数据，被游戏主线程调用
    @Override
    public void move() {
        if(left&&getX()>0){
            setX(getX()-6);
        }if(right&&getX()<900-getW()-5){
            setX(getX()+6);
        }if(up&&getY()>0){
            setY(getY()-6);
        }if(down&&getY()<600-getH()-30){
            setY(getY()+ 6);
        }
    }


    int updateTime=0;
    //根据状态改变数据，被游戏主线程调用
    @Override
    protected void updateImage(int gameTime) {
        setImageIcon(imageMap.get(direct));
    }


    //发射子弹方法
    int shotTime=0;
    @Override
    protected void shot(int gameTime) {
        if(!shoter){
            return;//如果不是发射状态，那么就不用调用子弹
        }
        //解决射速过快方法1：单点射击
        //shoter=false;//每次发射一颗子弹后，立即停止射击，即使你长按着射击键，也没用，因为这里判定为false
        //方法2：时间控制
        if(gameTime-shotTime>10){//当有一定控制时间，才允许发射子弹
            shotTime=gameTime;
            //                                              为子弹传入玩家坦克的值
            BaseElement element = new PlayShoter().createElement(initShoter());
            PlayShoter.count+=1;
            //将子弹加入元素管理器中，为什么不是载入，载入个屁，子弹是玩家创建的，一开始不用载入
            EleManager.getEleManager().getGameElements().get(GameElement.PLAYSHOTER).add(element);
        }
    }


    //这toString应该用一个自定义方法代替，用来为子弹赋初始值
    //这就是那个方法
    public String initShoter(){
        int x=getX();int y=getY();
        switch (direct){
            case "up":x+=20;break;
            case "left":y+=20;break;
            case "right":x+=50;y+=20;break;
            case "down":y+=50;x+=20;break;
        }
        return "x:"+x+",y:"+y+",direct:"+direct;
    }


    @Override
    public BaseElement createElement(String str) {
        String[] split = str.split(",");
        setX(Integer.parseInt(split[0]));
        setY(Integer.parseInt(split[1]));
        ImageIcon imageIcon = imageMap.get("up");//初始值就是up
        setW(imageIcon.getIconWidth());
        setH(imageIcon.getIconHeight());
        setImageIcon(imageIcon);
        return this;
    }
}
